package com.franklin.ideaplugin.api.navigation.json;

import cn.hutool.core.collection.CollectionUtil;
import com.franklin.ideaplugin.api.ui.editor.CustomEditor;
import com.franklin.ideaplugin.api.utils.JsonPathUtils;
import com.franklin.ideaplugin.api.utils.PsiUtil;
import com.franklin.ideaplugin.easytesting.thread.EasyTestingThreadPool;
import com.google.common.collect.Lists;
import com.intellij.json.JsonElementTypes;
import com.intellij.model.Symbol;
import com.intellij.model.psi.ImplicitReferenceProvider;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Editor;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiElementResolveResult;
import com.intellij.psi.PsiField;
import com.intellij.psi.ResolveResult;
import com.intellij.psi.impl.source.tree.LeafPsiElement;
import com.intellij.psi.util.PsiEditorUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.awt.*;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicReference;

/**
 * @author Ye Junhui
 * @since 2023/7/22
 */
public class EntityJsonImplicitReferenceProvider implements ImplicitReferenceProvider {

    @Override
    public @NotNull Collection<? extends Symbol> resolveAsReference(@NotNull PsiElement element) {
        try {
            if (!(element instanceof LeafPsiElement)){
                return Collections.emptyList();
            }
            LeafPsiElement leafPsiElement = (LeafPsiElement) element;
            if (!JsonElementTypes.DOUBLE_QUOTED_STRING.equals(leafPsiElement.getElementType())){
                return Collections.emptyList();
            }
            EasyTestingThreadPool.getBizThreadPool().execute(() -> {
                EventQueue.invokeLater(() -> {
                    try {
                        findAndNavigate(element);
                    } catch (Throwable throwable) {
                        //ignore
                    }
                });
            });

        } catch (Throwable t) {
            t.printStackTrace();
        }
        return Collections.emptyList();
    }

    /**
     * 寻找并导航
     * @param element
     */
    private void findAndNavigate(PsiElement element){
        Editor editor = PsiEditorUtil.getInstance().findEditorByPsiElement(element);
        if (Objects.isNull(editor)){
            return;
        }
        Container parent = editor.getComponent().getParent();
        if (Objects.isNull(parent)) {
            return;
        }
        if (!(parent instanceof CustomEditor)) {
            return;
        }
        CustomEditor customEditor = (CustomEditor) parent;

        //并发环境必须使用循环
        while (!customEditor.isCtrlPressed() || customEditor.isEditing()){
            return;
        }
        customEditor.setCtrlPressed(false);

        //解析JSON层级
        List<PsiUtil.FieldMethod> fieldMethodList = JsonPathUtils.resolveCurrentPathFields(element, customEditor);
        if (CollectionUtil.isEmpty(fieldMethodList)){
            return;
        }

        //当前字段
        String text = element.getText();
        String realText = text.substring(1, text.length() - 1);

        //寻找当前字段
        for (PsiUtil.FieldMethod fieldMethod : fieldMethodList) {
            PsiField field = fieldMethod.getField();
            if (Objects.nonNull(field)){
                if (field.getName().equals(realText)){
                    ApplicationManager.getApplication().invokeLater(() -> {
                        field.navigate(true);
                    });
                }
            }
        }
    }
}
